﻿using System;
using Newtonsoft.Json;
using Volo.Abp.DependencyInjection;
using Volo.Abp;

namespace Joy.Erp.BasicArchives.Core.UniqueCodes
{
    public class PropertySegment : ISegment, ITransientDependency
    {
        protected PropertySegmentConfigrationObject ConfigrationObject { get; set; }

        public void Init(string configration)
        {
            ConfigrationObject = JsonConvert.DeserializeObject<PropertySegmentConfigrationObject>(configration);
        }

        public string GetCode(IUniqueCode entity)
        {
            if (string.IsNullOrEmpty(ConfigrationObject.PropertyName))
            {
                throw new BusinessException("PropertyName cannot be empty");
            }

            var propertyPath = ConfigrationObject.PropertyName.Split('.');

            object currentValue = entity;
            foreach (var propertyName in propertyPath)
            {
                if (currentValue == null)
                {
                    return string.Empty;
                }

                var propertyInfo = currentValue.GetType().GetProperty(propertyName);
                if (propertyInfo == null)
                {
                    throw new BusinessException($"Property {propertyName} not found in path {ConfigrationObject.PropertyName}")
                        .WithData("PropertyName", ConfigrationObject.PropertyName)
                        .WithData("InvalidPropertyName", propertyName);
                }

                currentValue = propertyInfo.GetValue(currentValue);
            }

            if (currentValue == null)
            {
                return string.Empty;
            }

            // 检查是否存在值映射
            if (ConfigrationObject.ValueMappings != null &&
                ConfigrationObject.ValueMappings.TryGetValue(currentValue.ToString(), out string mappedValue))
            {
                return mappedValue;
            }

            // 如果没有映射，使用默认格式化
            if (string.IsNullOrEmpty(ConfigrationObject.Format))
            {
                return currentValue.ToString();
            }

            if (currentValue is IFormattable formattable)
            {
                return formattable.ToString(ConfigrationObject.Format, null);
            }

            return currentValue.ToString();
        }
    }
}
